var express 		= require('express');
var mysql   		= require('mysql');
var config  		= require('../config.json');
var sqlconfig 		= config.mysql;
var router  		= express.Router();
var pool    		= mysql.createPool(sqlconfig);

/*
  Name: data
  Args:
	data:data to be return
	res :response to write data
  Return : 
	Valid String for Client to use
  Description：
	  Return the valid  Data String to client if there is no error
*/

function data(data,res)
{
	console.log("LOG:RESPONSE:"+JSON.stringify(data));
	return res.end(JSON.stringify({err:0,response:data}));
}

/*
  Name: error
  Args:
	res:response to write err
	err:error message to return
	errcode: description of an error
  Return : 
	Valid String for Client to use
  Description：
	Return the error message to the client 
*/

function error(err,errcode,res)
{
	console.log("LOG:ERROR:"+errcode);
	return res.end(JSON.stringify({err : err,errcode : errcode}));
}

/*
  Name: BeforeAspect 
  Args: 
	request:Object
  Return: 
	data return from this aspect
  Description:
	preprocessor
*/

function BeforeAspect(request)
{
	
	console.log("LOG:REQUEST:"+JSON.stringify(request));
	return request;
}

/*
  Name:Student_Get_Subject[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get all subjects
*/
function Student_Get_Subject(req,res,next)
{
	var query = "SELECT hw.subject_id, s.subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` s ON hw.subject_id = s.subject_id ORDER BY hw_time DESC";
	try{
		var args = BeforeAspect(req.body);
		if(typeof(req.session.user) !=  'object' )
		{
			
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'PARENT' && req.session.user_type != 'STUDENT')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];
		query_args.push(req.session.user['class_id']);
		
		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(300,err,res);
				return;
			}
			else if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}
/*
  Name:Student_Get_All[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get all homework
*/

function Student_Get_All(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` s ON hw.subject_id = s.subject_id ORDER BY hw_time DESC LIMIT ?,?"
	try{
		var args = BeforeAspect(req.body);
		if(typeof(req.session.user) !=  'object' )
		{
			
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'PARENT' && req.session.user_type != 'STUDENT')
		{
			error(403,"Permission Denied",res);
			return;
		}
		
		if(typeof(args['limit']) == 'undefined' 
			|| typeof(args['count']) == 'undefined')
		{
			error(401,"Invalid Argument",res);
			return;				
		}		
		
		var query_args = [];
		query_args.push(req.session.user['class_id']);
		query_args.push(args['limit']);
		query_args.push(args['count']);
		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			else if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Student_Get_Scope_Subject[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			subject_id: subject_id to scope
			subject_name[Optional]:subject_name to scope
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get homework with scope subject
*/

function Student_Get_Scope_Subject(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE hw.subject_id = ? ORDER BY hw_time DESC LIMIT ?,?; ";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'PARENT' && req.session.user_type != 'STUDENT')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];
		query_args.push(req.session.user['class_id']);

		if(typeof(args['subject_id']) != 'number'
		 )
		{
			if(typeof(args['subject_name']) == 'string')
			{
				query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE subject_name = ? ORDER BY hw_time DESC LIMIT ?,?; ";
				query_args.push(args['subject_name']);
			}
			else
			{
				error(401,"Invalid Argument",res);
				return;
			}
			
		}
		else
		{
			query_args.push(args['subject_id']);
		}

		if(typeof(args['limit']) != 'number'
		|| typeof(args['count']) != 'number')
		{
			error(401,"Invalid Argument",res);
			return;
		}		


		query_args.push(args['limit']);
		query_args.push(args['count']);
		
		console.log(query_args)
		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			else if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Student_Get_Scope_hw_time[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			hw_time_l : left_limit of hw_time
			hw_time_r : rgiht_limit of hw_time
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get homework with scope hw_time
*/

function Student_Get_Scope_hw_time(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE hw_time BETWEEN ? AND ? ORDER BY hw_time DESC LIMIT ?,?; ";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'PARENT' && req.session.user_type != 'STUDENT')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];
		query_args.push(req.session.user['class_id']);

		if(	typeof(args['hw_time_l']) == 'undefined' 
			|| typeof(args['hw_time_r']) == 'undefined'
			|| typeof(args['limit']) == 'undefined'
			|| typeof(args['count']) == 'undefined')
		{
			error(401,"Invalid Argument",res);
			return;				
		}
		else
		{
			query_args.push(args['hw_time_l']);
			query_args.push(args['hw_time_r']);
			query_args.push(args['limit']);
			query_args.push(args['count']);
		}

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Student_Get_Scope_hw_deadline[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			hw_deadline_l : left limit of hw_deadline
			hw_deadline_r : right limit og hw_deadline
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get homework with scope hw_deadline
*/

function Student_Get_Scope_hw_deadline(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE hw_deadline BETWEEN ? AND ? ORDER BY hw_time DESC LIMIT ?,?; ";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'PARENT' && req.session.user_type != 'STUDENT')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];
		query_args.push(req.session.user['class_id']);

		if(typeof(args['hw_deadline_l']) == 'undefined' 
			|| typeof(args['hw_deadline_r']) == 'undefined'
			|| typeof(args['limit']) == 'undefined' 
			|| typeof(args['count']) == 'undefined')
		{
			error(401,"Invalid Argument",res);
			return;				
		}
		else
		{
			query_args.push(args['hw_deadline_l']);
			query_args.push(args['hw_deadline_r']);
			query_args.push(args['limit']);
			query_args.push(args['count']);
		}

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Teacher_Get_All[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			class_id : class id to get homework list
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get homework of a class
*/

function Teacher_Get_All(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id ORDER BY hw_time DESC LIMIT ?,?; ";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'TEACHER')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];
		
		if(typeof(args['class_id']) == 'undefined'
		|| typeof(args['limit']) == 'undefined'
		|| typeof(args['count']) == 'undefined')
		{
			error(401,"Invalid Argument",res);
			return;				
		}
		else
		{
			query_args.push(args['class_id']);
			query_args.push(args['limit']);
			query_args.push(args['count']);
		}

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Teacher_Get_Scope_Subject[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			class_id : class id to get homework
			subject_id : subject_id to scope homework
			subject_name [Optional] : subject_name to scope homework 
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get homework of a class with subject scope
*/

function Teacher_Get_Scope_Subject(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE hw.subject_id = ? ORDER BY hw_time DESC LIMIT ?,?; ";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'TEACHER')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];

		if(typeof(args['class_id']) != 'number')
		{
			error(401,"Invalid Argument",res);
			return;
		}
		else
		{
			query_args.push(args['class_id']);
		}

		if(typeof(args['subject_id']) != 'number')
		{
			
			if(typeof(args['subject_name']) == 'string')
			{
				query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE subject_name = ? ORDER BY hw_time DESC LIMIT ?,?; ";
				query_args.push(args['subject_name']);
			}
			else
			{
				error(401,"Invalid Argument",res);
				return;
			}							
		}
		else
		{
			query_args.push(args['subject_id']);
		}

		if(typeof(args['limit']) != 'number'
		|| typeof(args['count']) != 'number')
		{
			error(401,"Invalid Argument",res);
			return;
		}
		else
		{
			query_args.push(args['limit']);
			query_args.push(args['count']);
		}
		
		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			else if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Teacher_Get_Scope_hw_time[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			class_id : class to get homework
			hw_time_l : left limit of hw_time
			hw_time_r : right limit of hw_time
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get homework of a class with hw_time scope
*/

function Teacher_Get_Scope_hw_time(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE hw_time BETWEEN ? AND ? ORDER BY hw_time DESC LIMIT ?,?; ";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'TEACHER')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];

		if(typeof(args['class_id']) != 'number' 
			|| typeof(args['hw_time_l']) != 'string' 
			|| typeof(args['hw_time_r']) != 'string')
		{
			error(401,"Invalid Argument",res);
			return;		
		}
		else
		{
			query_args.push(args['class_id']);
			query_args.push(args['hw_time_l']);
			query_args.push(args['hw_time_r']);
		}
		
		if(typeof(args['limit']) != 'number'
		|| typeof(args['count']) != 'number')
		{
			error(401,"Invalid Argument",res);
			return;
		}
		else
		{
			query_args.push(args['limit']);
			query_args.push(args['count']);
		}		

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			else if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Teacher_Get_Scope_hw_deadline[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			class_id : class to get homework
			hw_deadline_l : left limit of hw_deadline
			hw_deadline_r : right limit of hw_deadline
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	get homework of a class with hw_deadline scope
*/

function Teacher_Get_Scope_hw_deadline(req,res,next)
{
	var query = "SELECT hw.*,subject_name FROM (SELECT * FROM homework WHERE class_id = ? ) hw LEFT JOIN `subject` ON hw.subject_id = `subject`.subject_id WHERE hw_deadline BETWEEN ? AND ? ORDER BY hw_time DESC LIMIT ?,?; ";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'TEACHER')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];

		if(typeof(args['class_id']) != 'number' 
			|| typeof(args['hw_deadline_l']) != 'string' 
			|| typeof(args['hw_deadline_r']) != 'string')
		{
			error(401,"Invalid Argument",res);
			return;		
		}
		else
		{
			query_args.push(args['class_id']);
			query_args.push(args['hw_deadline_l']);
			query_args.push(args['hw_deadline_r']);
		}

		if(typeof(args['limit']) != 'number'
		|| typeof(args['count']) != 'number')
		{
			error(401,"Invalid Argument",res);
			return;
		}
		else
		{
			query_args.push(args['limit']);
			query_args.push(args['count']);
		}

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			if(rows.length > 0)
			{
				data(rows,res);
			}
			else
			{
				error(303,"No data avalible",res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Teacher_Add_Homework[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			class_id : class to add homework
			subject_id : subject to add homework to
			hw_content : hw_content
			hw_time	   : hw_time
			hw_deadline: hw_deadline
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	Add homework to a class
*/

function Teacher_Add_Homework(req,res,next)
{
	var query = "INSERT INTO homework SET ?;";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'TEACHER')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = {};

		if(typeof(args['class_id']) != 'number' 
			|| typeof(args['subject_id']) != 'number' 
			|| typeof(args['hw_content']) != 'string' 
			|| typeof(args['hw_time']) != 'string' 
			|| typeof(args['hw_deadline']) != 'string' 
			)
		{
			error(401,"Invalid Argument",res);
			return;		
		}
		else
		{
			query_args['class_id']	= args['class_id'];
			query_args['subject_id']= args['subject_id'];
			query_args['hw_content']= args['hw_content'];
			query_args['hw_time']	= args['hw_time'];
			query_args['hw_deadline']= args['hw_deadline'];
		}

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			else
			{
				data(rows,res);
			}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

/*
  Name:Teacher_Delete_Homework[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			hw_id: hw_id of homework entity to delete 
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	Add homework to a class
*/

function Teacher_Delete_Homework(req,res,next)
{
	var query = "DELETE FROM homework WHERE hw_id = ?;";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'TEACHER')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];

		if(typeof(args['hw_id']) != 'number' )
		{
			error(401,"Invalid Argument",res);
			return;		
		}
		else
		{
			query_args.push(args['hw_id']);
		}

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			if(rows['affectedRows'] == 1)
				{
					req.session.user['teacher_password'] = args['teacher_password'];
					error(0,"Success",res);
				}
				else
				{
					error(1,"Failed",res);
				}
			return;
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}


/*
  Name:Teacher_Modify_Homework[I] 
  Args: 
	req:
		JSON :[ args] arguments of this query
			hw_id: hw_id of homework entity to delete 
			hw_content
	res: response to write data/error
	next:
  Return: 
  	None
  Description:
	Add homework to a class
*/

function Teacher_Modify_Homework(req,res,next)
{
	var query = "UPDATE homework SET hw_content = ? WHERE hw_id = ?;";
	try{
		var args = BeforeAspect(req.body);
		
		if(typeof(req.session.user) !=  'object' )
		{
			error(402,"Login First",res);
			return;
		}

		if(req.session.user_type != 'TEACHER')
		{
			error(403,"Permission Denied",res);
			return;
		}

		var query_args = [];

		if(typeof(args['hw_id']) != 'number' 
			|| typeof(args['hw_content']) != 'string'
			)
		{
			error(401,"Invalid Argument",res);
			return;		
		}
		else
		{
			query_args.push(args['hw_content']);
			query_args.push(args['hw_id']);
		}

		pool.query(query,query_args,
		function(err,rows,fileds)
		{
			if(err)
			{
				error(500,err,res);
				return;
			}
			if(rows['affectedRows'] == 1)
			{
				error(0,"Success",res);
			}
			else
			{
				error(1,"Failed",res);
			}
		});
	}
	catch(err)
	{
		error( -1 ,err,res);
	}
	return;
}

//Register '/' GET router
router.get('/', function(req, res, next) 
{
  data({},res);
});

//Register all routers 
var functions = {	 "/stu_all/"     	 : Student_Get_All
			,"/stu_get_subject/"	: Student_Get_Subject
			,"/stu_scope/subject"	: Student_Get_Scope_Subject
			,"/stu_scope/hw_time" 	: Student_Get_Scope_hw_time
			,"/stu_scope/hw_deadline" : Student_Get_Scope_hw_deadline
			,"/tea_all/"     	: Teacher_Get_All
			,"/tea_scope/subject"	: Teacher_Get_Scope_Subject
			,"/tea_scope/hw_time" 	: Teacher_Get_Scope_hw_time
			,"/tea_scope/hw_deadline" : Teacher_Get_Scope_hw_deadline				
			,"/tea_add" 	: Teacher_Add_Homework
			,"/tea_del" 	: Teacher_Delete_Homework 
			,"/tea_modify" : Teacher_Modify_Homework 
			}

for(var i in functions) 
{
	console.log("FUNCTION_LOADED(homework):"+i);
	router.post(i, functions[i]);
}

module.exports = router;
